#include "main.h"
#include "stm32f0xx_hal.h"
#include "userkey.h"

uint8_t keyInfo[4];      //0x11代表短按释放,0x21代表长按释放，0x00代表没有按键操作
uint8_t keyValue[4];
uint8_t keyState[4];


#define KEY_INFO_NULL                0X00
#define KEY_INFO_RELEASE             0X01   //按键按下又释放，包括短按释放和长按释放
#define KEY_INFO_SHORT_RELEASE       0X11   //短按并释放
#define KEY_INFO_LONG_RELEASE        0X21   //长按释放 
#define KEY_INFO_PRESS               0X02   //按键正在按下状态
#define KEY_INFO_SHORT_PRESS         0X12   //按键正处于短时间按下状态
#define KEY_INFO_LONG_PRESS          0X22   //按键正处于长时间按下状态

//按键状态机
#define KEY_STATE_NULL               0X00
#define KEY_STATE_PRESS_FIRST        0X01
#define KEY_STATE_PRESS_OK           0X02   //经过滤波后确定按下
#define KEY_STATE_PRESS_LONG         0X03   //按键长按两秒
#define KEY_STATE_RELEASE            0X05   //按键释放
#define KEY_STATE_SHORT_RELEASE      0X06
#define KEY_STATE_LONG_RELEASE       0X07 

void user_keyInit()
{
	keyInfo[0]=KEY_INFO_NULL;
	keyInfo[1]=KEY_INFO_NULL;
	keyInfo[2]=KEY_INFO_NULL;
	keyInfo[3]=KEY_INFO_NULL;
	
}
void user_keyScan()
{
	uint8_t i=0;
	static uint16_t keyPressTime[4];
	
	keyValue[0]=HAL_GPIO_ReadPin(KEYA_GPIO_Port,KEYA_Pin);
	keyValue[1]=HAL_GPIO_ReadPin(KEYB_GPIO_Port,KEYB_Pin);
	keyValue[2]=HAL_GPIO_ReadPin(KEYC_GPIO_Port,KEYC_Pin);
	keyValue[3]=HAL_GPIO_ReadPin(KEYD_GPIO_Port,KEYD_Pin);
	for(i=0;i<4;i++)
	{
		switch (keyState[i])
		{
			case KEY_STATE_NULL:
				if(keyValue[i]==0)
				{
					keyState[i]=KEY_STATE_PRESS_FIRST;
					keyPressTime[i]=0;   //首次按键按下，把计数值清0
				}
				else   //按键没有按下，一直计时 
				{
					keyPressTime[i]++;
					if(keyPressTime[i]>=400)   //如果按键长时间没有操作，默认清除掉之前的按键消息
					{
						keyInfo[i]=KEY_INFO_NULL;
					}
				}
				break;
		  case KEY_STATE_PRESS_FIRST:
				keyPressTime[i]++; 
				if(keyPressTime[i]>=3)    //等待延时40ms用来滤波
				{
					if(keyValue[i]==0)
					{
						keyState[i]=KEY_STATE_PRESS_OK;
						keyPressTime[i]=0;   //确定按键按下，就把计数值清0
					}
					else
					{
						keyState[i]=KEY_STATE_NULL;
					}				
				}
				break;
			case KEY_STATE_PRESS_OK:
				keyPressTime[i]++;
				if(keyValue[i]==1)
				{
					keyState[i]=KEY_STATE_SHORT_RELEASE;
				}	
				else 
				{
					if(keyPressTime[i]>=200)   //按键超过2秒钟判断为长按键
					{
						  keyState[i]=KEY_STATE_PRESS_LONG;
						  keyInfo[i]=KEY_INFO_LONG_PRESS;
						  keyPressTime[i]=0;    //计数器清0
					}
				}
				break;
			case KEY_STATE_PRESS_LONG:
				if(keyValue[i]==1)
				{
					keyState[i]=KEY_STATE_LONG_RELEASE;							
						
				}
				break;
			case KEY_STATE_LONG_RELEASE:
				if(keyValue[i]==1)  //be sure the key is pressed again
				{
					keyState[i]=KEY_STATE_NULL;
					keyInfo[i]=KEY_INFO_LONG_RELEASE;
				}
				else
				{
					keyState[i]=KEY_STATE_PRESS_LONG;
				}
				break;				
			case KEY_STATE_SHORT_RELEASE:
				if(keyValue[i]==1)   //be sure the key is pressed again
				{
					keyState[i]=KEY_STATE_NULL;
					keyInfo[i]=KEY_INFO_SHORT_RELEASE;
					HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
				}
				else
				{
					keyState[i]=KEY_STATE_PRESS_OK;
				}
				break;
		}
	}	
}
//按键短按并释放状态查询，有按下返回1，无返回0
//参数：keyNum ：KEY_A  KEY_B  KEY_C  KEY_D
uint8_t user_keyShortRelease(uint8_t keyNum)
{
	if(keyInfo[keyNum]==KEY_INFO_SHORT_RELEASE)
	{
		keyInfo[keyNum]=0;
		return 1;
	}
	else return 0;
}

//按键长按并释放状态查询，有按下返回1，无返回0
//参数：keyNum ：KEY_A  KEY_B  KEY_C  KEY_D
uint8_t user_keyLongRelease(uint8_t keyNum)
{
	if(keyInfo[keyNum]==KEY_INFO_LONG_RELEASE)
	{
		keyInfo[keyNum]=0;
		return 1;
	}
	else return 0;
}

//按键长按保持状态查询，有按下返回1，无返回0
//参数：keyNum ：KEY_A  KEY_B  KEY_C  KEY_D
uint8_t user_keyLongHold(uint8_t keyNum)
{
	if(keyInfo[keyNum]==KEY_INFO_LONG_PRESS)
	{
		return 1;
	}
	else return 0;
}
